package com.simulation.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.simulation.common.utils.SecurityUtils;
import com.simulation.common.utils.StringUtils;
import com.simulation.web.dto.TechPostDTO;
import com.simulation.web.domain.TechPost;
import com.simulation.web.entity.OssFile;
import com.simulation.web.mapper.PostMapper;
import com.simulation.web.service.PostService;
import com.simulation.web.utils.PostStatusEnum;
import com.simulation.web.vo.TechPostVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


@Service
@AllArgsConstructor
@Slf4j
public class PostServiceImpl implements PostService {

    private final PostMapper postMapper;

    private final MinioTemplate minioTemplate;

    @Override
    public PageInfo<TechPostVO> getPage(TechPostDTO techPostDTO) {
        PageHelper.startPage(techPostDTO.getPageNum(), techPostDTO.getPageSize());
        List<String> statusList = new ArrayList<>();
        if (StrUtil.isBlank(techPostDTO.getStatus())) {
            statusList.add(PostStatusEnum.PRIVATE.name().toLowerCase());
            statusList.add(PostStatusEnum.PUBLISHED.name().toLowerCase());
            statusList.add(PostStatusEnum.DRAFT.name().toLowerCase());
        } else {
            statusList.addAll(Arrays.asList(techPostDTO.getStatus().split(",")));
        }
        List<TechPostVO> postList = postMapper.getPage(techPostDTO, statusList);
        return new PageInfo<>(postList);
    }

    /**
     * 查询所有记录
     *
     * @return 返回集合，没有返回空List
     */
    @Override
    public List<TechPostVO> listAll() {
        return postMapper.listAll();
    }


    /**
     * 根据主键查询
     *
     * @param id 主键
     * @return 返回记录，没有返回null
     */
    @Override
    public TechPostVO getById(Long id) {
        // TODO 更新浏览数
        return postMapper.getById(id);
    }

    /**
     * 新增，插入所有字段
     *
     * @param techPost 新增的记录
     * @return 返回影响行数
     */
    @Override
    public int insert(TechPost techPost) {
        return postMapper.insert(techPost);
    }

    /**
     * 新增，忽略null字段
     *
     * @param techPost 新增的记录
     * @return 返回影响行数
     */
    @Override
    public int insertIgnoreNull(TechPost techPost, String bucketName) {
        techPost.setUserId(SecurityUtils.getUserId());
        techPost.setUpdateTime(new Date());
        InputStream in = minioTemplate.getObject(bucketName, "template/projectTemplate.zip");
        OssFile ossFile = minioTemplate.upLoadFile("template", "projectTemplate", MinioTemplate.getFileExtension("projectTemplate.zip"), in);
        techPost.setCode(ossFile.getName().replace("http://43.138.128.114:9000/","https://isp.yunfengcloud.cn/file/"));
        if (!StringUtils.isEmpty(techPost.getEvaluateUrl())) {
            techPost.setEvaluateUrl(techPost.getEvaluateUrl().replace("http://43.138.128.114:9000/","https://isp.yunfengcloud.cn/file/"));
        }
        log.info("==== techPost:{}", JSONObject.toJSONString(techPost));
        return postMapper.insertIgnoreNull(techPost);
    }

    /**
     * 修改，修改所有字段
     *
     * @param techPost 修改的记录
     * @return 返回影响行数
     */
    @Override
    public int update(TechPost techPost) {
        handlePost(techPost);
        techPost.setUpdateTime(new Date());
        return postMapper.update(techPost);
    }

    /**
     * 修改，忽略null字段
     *
     * @param techPost 修改的记录
     * @return 返回影响行数
     */
    @Override
    public int updateIgnoreNull(TechPost techPost) {
        handlePost(techPost);
        return postMapper.updateIgnoreNull(techPost);
    }

    /**
     * 删除记录（此方法为软删除）
     *
     * @param techPost 待删除的记录
     * @return 返回影响行数
     */
    @Override
    public int delete(TechPost techPost) {
        techPost.setStatus(PostStatusEnum.DELETED.name().toLowerCase());
        // 删除对应的文件资源
        if (StrUtil.isNotBlank(techPost.getCode())) {
            minioTemplate.removeFile(techPost.getCode());
        }
        if (StrUtil.isNotBlank(techPost.getEvaluateUrl())) {
            minioTemplate.removeFile(techPost.getEvaluateUrl());
        }
        if (StrUtil.isNotBlank(techPost.getCoverImage())) {
            minioTemplate.removeFile(techPost.getCoverImage());
        }
        return updateIgnoreNull(techPost);
    }

    @Override
    public void deleteById(List<Long> idList) {
        List<TechPostVO> techPostVOList = getByIdList(idList);
        for (TechPostVO techPostVO : techPostVOList) {
            TechPost techPost = new TechPost();
            BeanUtil.copyProperties(techPostVO, techPost);
            delete(techPost);
        }
    }

    @Override
    public int updateStatus(TechPost techPost) {
        handlePost(techPost);
        return postMapper.updateIgnoreNull(techPost);
    }

    @Override
    public PageInfo<TechPost> getPostByUserFocused(Integer pageNum, Integer pageSize, Long userId) {
        PageHelper.startPage(pageNum, pageSize);
        List<TechPost> list = postMapper.getPostByUserFocused(userId);
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<TechPost> getPostByUserLikes(Integer pageNum, Integer pageSize, Long userId) {
        PageHelper.startPage(pageNum, pageSize);
        List<TechPost> list = postMapper.getPostByUserLikes(userId);
        return new PageInfo<>(list);
    }

    @Override
    public PageInfo<TechPostVO> getPostByCollectionId(Long collectionId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<TechPostVO> list = postMapper.getPostByCollectionId(collectionId);
        return new PageInfo<>(list);
    }

    /**
     * 排行榜
     * @return
     */
    @Override
    public List<TechPostVO> selectViewCount(){
        return postMapper.selectViewCount();
    }

    /**
     * 推荐榜
     * @return
     */
    @Override
    public List<TechPostVO> selectFavoriteCount(){
        return postMapper.selectFavoriteCount();
    }

    /**
     * id
     * @param userId
     * @return
     */
    @Override
    public List<TechPostVO> selectFollowCount(Long userId){
        return postMapper.selectFollowCount(userId);
    }

    @Override
    public Boolean isCopy(Long userId, Long source) {
        return postMapper.isCopy(userId, source) > 0 ? Boolean.TRUE : Boolean.FALSE;
    }

    @Override
    public Long copyPost(TechPost techPost) {
        techPost.setCollectionId(null);
        techPost.setViewCount(0);
        techPost.setFavoriteCount(0);
        techPost.setCommentCount(0);
        techPost.setFollowCount(0);
        techPost.setEvaluateResult(null);
        techPost.setPublishTime(new Date());

//        if (StrUtil.isNotBlank(techPost.getCode())) {
//            String newCode = minioTemplate.copy("template", "projectTemplate", MinioTemplate.getFileExtension(techPost.getCode()), techPost.getCode());
//            techPost.setCode(newCode);
//        }

//        if (StrUtil.isNotBlank(techPost.getEvaluateUrl())) {
//            String evaluateUrl = minioTemplate.copy("template", "projectTemplate", MinioTemplate.getFileExtension(techPost.getEvaluateUrl()), techPost.getEvaluateUrl());
//            techPost.setEvaluateUrl(evaluateUrl);
//        }

        if (StrUtil.isNotBlank(techPost.getCoverImage())) {
//            String coverImage = minioTemplate.copy("template", "projectTemplate", MinioTemplate.getFileExtension(techPost.getCoverImage()), techPost.getCoverImage());
            techPost.setCoverImage(techPost.getCoverImage());
        }
        insert(techPost);
        return techPost.getId();
    }

    @Override
    public List<TechPostVO> getByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) return new ArrayList<>();
        return postMapper.getByIdList(idList);
    }

    @Override
    public void updatePostWorkspaceId(Long projectId, String workspaceId,String code,String environment) {
        postMapper.updateWorkspace(workspaceId, projectId,code,environment);
    }

    /**
     * 处理项目信息的公共方法
     * @param techPost
     */
    private void handlePost(TechPost techPost) {
        if (StrUtil.isBlank(techPost.getStatus())) {
            return;
        }
        switch (PostStatusEnum.getByName(techPost.getStatus())) {
            case PUBLISHED:
                techPost.setPublishTime(new Date());
                break;
            case DELETED:
                // 如果变更为发布状态，需要更新发布时间
                techPost.setUpdateTime(new Date());
                break;
        }
    }
}